/**
 * 
 */
package il.ac.bgu.cs.heuristics.integration;

import il.ac.bgu.cs.heuristics.core.HeuristicEngineComplex;
import il.ac.bgu.cs.heuristics.core.IHeuristicsEngine;
import il.ac.bgu.cs.heuristics.core.SameInitGoalPairException;
import il.ac.bgu.cs.heuristics.graph.GraphBuildEssentials;
import il.ac.bgu.cs.heuristics.graph.types.IState;

import java.util.Comparator;

import javaff.planning.FFState;

/**
 * A comparator which performs comparison with heuristic values of it's
 * candidates.
 * 
 * <p>
 * the heuristic values is taken by adapting FFState to {@link IState} and then
 * invoking {@link HeuristicEngineComplex#getHValue(IState, IState)} on the
 * adapted States
 * </p>
 * 
 * @author Ronen Pinko
 * 
 */
public class HeuristicValueAdaptingComparator implements Comparator<FFState> {

	private final IHeuristicsEngine		heuristicsEngine;
	private final IState				goal;
	private final GraphBuildEssentials	graphEssentials;

	public HeuristicValueAdaptingComparator(IHeuristicsEngine heuristicEngine,
			IState goal, GraphBuildEssentials graphEssentials) {
		this.heuristicsEngine = heuristicEngine;
		this.goal = goal;
		this.graphEssentials = graphEssentials;
	}

	@Override
	public int compare(FFState ffState1, FFState ffState2) {
		int result = 0;
		final IState state1 = IntegrationUtils.stateFrom(ffState1,
				graphEssentials);
		final IState state2 = IntegrationUtils.stateFrom(ffState2,
				graphEssentials);
		Integer hVal1 = null;
		try {
			hVal1 = heuristicsEngine.getHValue(state1, goal);
		} catch (SameInitGoalPairException e) {
			hVal1 = 4;// e.getEstimateHvalue();
		}
		Integer hVal2 = null;
		try {
			hVal2 = heuristicsEngine.getHValue(state2, goal);
		} catch (SameInitGoalPairException e) {
			hVal2 = e.getEstimateHvalue();
		}
		result = hVal1.compareTo(hVal2);
		if (result == 0) {
			final Integer hash1 = ffState1.hashCode();
			final Integer hash2 = ffState2.hashCode();
			result = hash1.compareTo(hash2);
		}
		return result;
	}
}
